package net.adriana.esaytool;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.List;

import net.adriana.Fac;
import net.adriana.bean.Column;
import net.adriana.bean.Table;

public class ClassCreate {
	private String packagePath;
	
	public void create(){
		packagePath = Fac.packageName.replace(".", "\\");
		Table[] tables = Fac.schema.getTables();
		String[] tablesName = Fac.schema.getStdTablesName();
		File pack = new File(Fac.filePath + "\\" + packagePath);
		if(!pack.exists()){
			if(!pack.mkdirs())
				Logger.log(Logger.CHECK, "包创建成功" + Fac.filePath + "\\" + packagePath);
			else{
				Fac.isError = true;
				Logger.log(Logger.ERROR, "包创建失败" + Fac.filePath + "\\" + packagePath);
			}
		}else{
			Logger.log(Logger.WARING, "包已存在" + Fac.filePath + "\\" + packagePath);
		}
		for (int i = 0; i < tables.length; i++) {
			File f = new File(Fac.filePath + "\\" + packagePath, tablesName[i] + ".java");
			if(!f.exists()){
				try {
					f.createNewFile();
					Logger.log(Logger.CHECK, "文件创建成功" + Fac.filePath + "\\" + tablesName[i] + ".java");
				} catch (IOException e) {
					Fac.isError = true;
					Logger.log(Logger.ERROR, "文件创建失败" + e.getMessage());
					return;
				}
			}else{
				Fac.isError = true;
				Logger.log(Logger.ERROR, "文件已存在创建失败" + Fac.filePath + "\\" + packagePath + "\\" + tablesName[i] + ".java");
				return;
			}
			try {
				fillContent(f,tables[i]);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		Fac.isDone = true;
		Logger.log(Logger.CHECK,"\n----------------------------------完成\n\n");
	}
	
	@SuppressWarnings("resource")
	private boolean fillContent(File f,Table table) throws IOException{
		Column[] cols = table.getCols();
		PrintWriter out = new PrintWriter(new BufferedWriter(
				new OutputStreamWriter(new FileOutputStream(f),"UTF-8")));
		String className = table.getStdTableName() + ".java";
		if(!f.canWrite()){
			Fac.isError = true;
			Logger.log(Logger.ERROR, "文件写入失败" + f );
			return false;
		}else{
			if(!(Fac.packageName.equals("") || Fac.packageName.equals(" ")))
				out.println("package " + Fac.packageName +";");
			out.println();
			if(table.isImpleContains("Serializable")){
				out.println("import java.io.Serializable;");
			}
			out.println("import java.util.*;");
			out.println();
			boolean isAddedAnno = false;
			for (Column col : cols) {
				if(!(col.getAnnoName().equals("") || col.getAnnoName().equals(" "))){
					isAddedAnno = true;
					break;
				}
			}
			if(isAddedAnno == true) out.println("import net.easymvc.annotation.Valid;");
			out.println();
			out.print("public class " + table.getStdTableName());
			if(table.isExtends()) out.print(" extends " + table.getExtends());
			if(table.isSelectedImple()){
				out.print(" implements ");
				List<String> strs = table.getInterfaceNames();
				for (int i = 0; i < strs.size(); i++) {
					if(i == strs.size() - 1)out.print(strs.get(i));
					else out.print(strs.get(i) + ", ");
				}
			}else if(table.isSelectedMethods()){
				if(table.isSelectedMethods("compareTo()")){
					out.print(" implements Comparable");
				}
			}
			out.print(" {");
			out.println();
			for (Column col : cols) {
				writeField(out, col);
			}
			Logger.log(Logger.CHECK, className + " 字段填充成功");
			writeConstructor(out,table);
			Logger.log(Logger.CHECK,className + " 构造器填充成功");
			for (Column col : cols) {
				writeGetterSetter(out, col.getStdTypeName(), col.getStdColName());
			}
			Logger.log(Logger.CHECK, className + " Getter,Setter填充成功");
			if(table.isSelectedMethods()){
				if(table.isSelectedMethods("toString()")){
					writeToString(out,table.getStdTableName(), table.getStdColsName());
					Logger.log(Logger.CHECK, className + " toString()填充完成");
				}
				if(table.isSelectedMethods("compareTo()")){
					writeCompareTo(out,table);
					Logger.log(Logger.CHECK, className + " compareTo()填充完成");
				}
			}
			out.println();
			out.println("}");
			out.println();
			out.flush();
			out.close();
			Logger.log(Logger.CHECK, className + " 填充完成");
		}
		return true;
	}
	
	private void writeCompareTo(PrintWriter out, Table table) throws IOException {
		out.println("	@Override");
		out.println("	public int compareTo(Object o) {");
		out.println("		// TODO Auto-generated method stub");
		out.println();
		out.println();
		out.println("		return 0;");
		out.println("	}");
		out.println();
		out.flush();
	}

	private void writeToString(PrintWriter out,String className, String[] colsName) throws IOException{
		out.println("	@Override");
		out.println("	public String toString() {");
		String str = "";
		for (int i = 0; i < colsName.length; i++) {
			if(i == 0)str += colsName[i] + "=\" + " + colsName[i] + "+ ";
			else if(i == colsName.length - 1)str += "\", " + colsName[i] + "=\" + " + colsName[i] + " + ";
			else str += "\", " + colsName[i] + "=\" + " + colsName[i] + " + ";
		}
		out.println("		return \"" + className + "[" + str + "\"]\";");
		out.println("	}");
		out.println();
	}

	private void writeGetterSetter(PrintWriter out, String type, String name) throws IOException{
		String methodName = name.substring(0, 1).toUpperCase() + name.substring(1);
		out.println("	public " + type + " get" + methodName + "() {");
		out.println("		return this." + name + ";");
		out.println("	}");
		out.println();
		out.println("	public void set" + methodName + "(" + type + " " + name + ") {");
		out.println("		this." + name + " = " + name +";");
		out.println("	}");
		out.println();
		out.flush();
	}
	
	private void writeConstructor(PrintWriter out,Table table) throws IOException{
		out.println();
		out.println("	public " + table.getStdTableName() + " () {");
		out.println("		super();");
		out.println("	}");
		out.println();
		Column[] cols = table.getCols();
		String str = "";
		String[] strs = table.getStdColsName();
		for (int i = 0; i < cols.length; i++) {
			if(i == cols.length - 1)str += cols[i].getStdTypeName() + " " + strs[i];
			else str += cols[i].getStdTypeName() + " " + strs[i] + ",";
		}
		out.println("	public " + table.getStdTableName() + " (" + str + ") {");
		for (int i = 0; i < strs.length; i++) {
			out.println("		this." + strs[i] + " = " + strs[i] + ";");
		}
		out.println("	}");
		out.println();
		out.flush();
	}
	
	private void writeField(PrintWriter out, Column col) throws IOException{
		String str = new String(col.getRemarks().getBytes(),"UTF-8");
		if(!(str.equals("") || str==null)){
			out.println("	/**");
			out.println("	 * " + str);
			out.println("	 */");
		}
		if(!(col.getAnnoName().equals("") || col.getAnnoName().equals(" "))){
			out.print("	@" + col.getAnnoName());
			if(!col.getAnnoPattern().equals("")) out.print("(pattern=\"" + col.getAnnoPattern() + "\"");
			else out.print("(pattern=\"\"");
			if(!col.getAnnoMassege().equals("")) out.print(",message=\"" + col.getAnnoMassege() + "\")");
			else out.print(",message=\"\")");
			out.println();
		}
		out.print("	private ");
		str = col.getStdTypeName();
		if(str==null){
			Logger.log(Logger.ERROR, "列数据类型获取失败" + col.getColName());
			return;
		}
		out.print(str+" ");
		str = col.getStdColName();
		out.println(str+";");
		out.println();
		out.flush();
	}
	
}
